package com.binhthuan.catechist.server.domain;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import com.google.gson.annotations.Expose;

/**
 * @author Giang Đinh - Lớp học, tương ứng với bảng <b>ec_course</b> trong cơ sở dữ
 *         liệu.
 */
@Entity
@Table(name = "ec_course")
public class Course extends AbstractObject {

    /**
     * Mã lớp học (dùng cho csdl).
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    @Expose
    private Integer id;

    /**
     * Mã lớp học (người dùng nhập).
     */
    @Column(name = "course_code", length = 10)
    @Expose
    private String code;

    /**
     * Tên lớp.
     */
    @Column(name = "course_name", length = 20)
    @Expose
    private String name;

    /**
     * Khối lớp.
     */
    @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.EAGER)
    @JoinColumn(name = "grade_id")
    @Expose
    private Grade grade;

    /**
     * Phòng học.
     */
    @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.EAGER)
    @JoinColumn(name = "venue_id")
    @Expose
    private Venue venue;

    /**
     * Ca học.
     */
    @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.EAGER)
    @JoinColumn(name = "shift_id")
    @Expose
    private Shift shift;
    
    /**
     * Bảng điểm danh.
     */
    @OneToMany(cascade = {CascadeType.ALL}, mappedBy = "course", fetch = FetchType.LAZY)
    private Set<AttendanceList> attendanceLists;

    /**
     * Năm học.
     */
    @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.EAGER)
    @JoinColumn(name = "year_id")
    @Expose
    private Year year;

    /**
     * Giáo lý viên phụ trách.
     */
    @ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.EAGER)
    @JoinTable(name = "ec_courses_trainers",
            joinColumns = {@JoinColumn(name = "course_id")},
            inverseJoinColumns = {@JoinColumn(name = "trainer_id")})
    @Expose
    private Set<Trainer> trainers;

    /**
     * Học viên.
     */
    @ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.LAZY)
    @JoinTable(name = "ec_courses_trainees",
            joinColumns = {@JoinColumn(name = "course_id")},
            inverseJoinColumns = {@JoinColumn(name = "trainee_id")})
    private Set<Trainee> trainees;

    /**
     * Thời khóa biểu.
     */
    @OneToMany(cascade=CascadeType.ALL, mappedBy = "course", fetch = FetchType.EAGER)
    private Set<Schedule> schedules;

    public Course() {
        trainers = new HashSet<Trainer>(0);
        trainees = new HashSet<Trainee>(0);
        schedules = new HashSet<Schedule>(0);
        attendanceLists = new HashSet<AttendanceList>(0);
    }

    /**
     * Lấy mã lớp học (dùng trong csdl).
     * 
     * @return Mã lớp học (dùng trong csdl).
     */
    public Integer getId() {
        return id;
    }

    /**
     * Gán mã lớp học (dùng trong csdl).
     * 
     * @param id
     *            Mã lớp học (dùng trong csdl).
     */
    public void setId(Integer id) {
        this.id = id;
    }

    /**
     * Lấy mã lớp học (người dùng nhập).
     * 
     * @return Mã lớp học (người dùng nhập).
     */
    public String getCode() {
        return code;
    }

    /**
     * Gán mã lớp học (người dùng nhập).
     * 
     * @param code
     *            Mã lớp học (người dùng nhập).
     */
    public void setCode(String code) {
        this.code = code;
    }

    /**
     * Lấy tên lớp.
     * 
     * @return Tên lớp.
     */
    public String getName() {
        return name;
    }

    /**
     * Gán tên lớp.
     * 
     * @param name
     *            Tên lớp.
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * Lấy khối lớp.
     * 
     * @return Khối lớp.
     */
    public Grade getGrade() {
        return grade;
    }

    /**
     * Gán khối lớp.
     * 
     * @param grade
     *            Khối lớp.
     */
    public void setGrade(Grade grade) {
        this.grade = grade;
    }

    /**
     * Lấy địa điểm học.
     * 
     * @return Địa điểm học.
     */
    public Venue getVenue() {
        return venue;
    }

    /**
     * Gán địa điểm học.
     * 
     * @param venue
     *            Địa điểm học.
     */
    public void setVenue(Venue venue) {
        this.venue = venue;
    }

    /**
     * Lấy ca học.
     * 
     * @return Ca học.
     */
    public Shift getShift() {
        return shift;
    }

    /**
     * Gán ca học.
     * 
     * @param shift
     *            Ca học.
     */
    public void setShift(Shift shift) {
        this.shift = shift;
    }

    /**
     * Lấy năm học.
     * 
     * @return Năm học.
     */
    public Year getYear() {
        return year;
    }

    /**
     * Gán năm học.
     * 
     * @param year
     *            Năm học.
     */
    public void setYear(Year year) {
        this.year = year;
    }

    /**
     * Lấy các giáo lý viên phụ trách.
     * 
     * @return Các giáo lý viên phụ trách.
     */
    public Set<Trainer> getTrainers() {
        return trainers;
    }

    /**
     * Gán giáo lý viên phụ trách.
     * 
     * @param trainers
     *            Các giáo lý viên phụ trách.
     */
    public void setTrainers(Set<Trainer> trainers) {
        this.trainers = trainers;
    }

    /**
     * Lấy các học viên.
     * 
     * @return Các học viên.
     */
    public Set<Trainee> getTrainees() {
        return trainees;
    }

    /**
     * Gán học viên.
     * 
     * @param trainees
     *            Các học viên.
     */
    public void setTrainees(Set<Trainee> trainees) {
        this.trainees = trainees;
    }

    /**
     * Lấy các thời khóa biểu.
     * 
     * @return Các thời khóa biểu.
     */
    public Set<Schedule> getSchedules() {
        return schedules;
    }

    /**
     * Gán thời khóa biểu.
     * 
     * @param schedules
     *            Các thời khóa biểu.
     */
    public void setSchedules(Set<Schedule> schedules) {
        this.schedules = schedules;
    }

    /**
     * @return the attendanceLists
     */
    public Set<AttendanceList> getAttendanceLists() {
        return attendanceLists;
    }

    /**
     * @param attendanceLists the attendanceLists to set
     */
    public void setAttendanceLists(Set<AttendanceList> attendanceLists) {
        this.attendanceLists = attendanceLists;
    }
}
